﻿using System;
using System.Collections.Generic;
using System.Linq;
using Algoritmia.DataStructures.Maps;
using Algoritmia.Schemes.DynamicProgramming;
using Algoritmia.SemiRings;
using Algoritmia.Utils;

namespace Algoritmia.Problems.GeneralizedCoinChange.ByScheme
{
    public class ForwardCoinChanger
    {
        private readonly DataStructures.Lists.IList<int> _values;
        private readonly ForwardDynamicProgrammingSolver<int,int,double> _solver;
        private readonly Func<int,int,double>_weightingFunction;

        public ForwardCoinChanger(DataStructures.Lists.IList<int> values, DataStructures.Lists.IList<double> weights,
                                  Func<IEnumerable<KeyValuePair<int,double>>,IMap<int,double>> createMap = null  )
        {
            _values = values;
            createMap = createMap ?? (it => AlgoritmiaFactory.Maps<int, double>.BuildDefault(it));
            var dict = createMap(values.Select((e, i) => new KeyValuePair<int, double>(e, weights[i])));
            _weightingFunction = (value,d) => dict[d];
            _solver = new ForwardDynamicProgrammingSolver<int, int, double>();
        }

        public double Solve(int Q)
        {
            var stateSpace = new MoneyChangeForwardStateSpace(Q, _values);
            return _solver.Solve(stateSpace, MinTropicalSemiRing<double>.GetInstance(), _weightingFunction);
        }

    }
}
